package com.example.core.datasource;

import com.example.core.context.CommonContext;
import com.example.core.context.CustomContext;
import com.example.util.BeanTool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.util.StringUtils;

public class DynamicDataSourceUtil {

    private static Logger logger = LoggerFactory.getLogger(DynamicDataSourceUtil.class);

    public static HikariDataSourceInfo getDynamicSource(String dataSourceApp) {
        // 如果传了app
        if (!StringUtils.hasLength(dataSourceApp)) {
            dataSourceApp = BeanTool.getProperty("app.datasource.default");
        }
        return checkGetDataSourceExists(dataSourceApp);
    }

    public static String getDefaultSource() {
        return BeanTool.getProperty("app.datasource.default");
    }

    private static HikariDataSourceInfo checkGetDataSourceExists(String dataSourceApp) {
        String driverClassNameKey = String.format("app.datasource.dynamic.%s.driverClassName", dataSourceApp);
        String jdbcUrlKey = String.format("app.datasource.dynamic.%s.jdbcUrl", dataSourceApp);
        String usernameKey = String.format("app.datasource.dynamic.%s.username", dataSourceApp);
        String passwordKey = String.format("app.datasource.dynamic.%s.password", dataSourceApp);

        String driverClassName = BeanTool.getProperty(driverClassNameKey);
        String jdbcUrl = BeanTool.getProperty(jdbcUrlKey);
        String username = BeanTool.getProperty(usernameKey);
        String password = BeanTool.getProperty(passwordKey);
        if (!StringUtils.hasLength(driverClassName) || !StringUtils.hasLength(jdbcUrl)
                || !StringUtils.hasLength(username) || !StringUtils.hasLength(password)) {
            throw new RuntimeException("datasource config error, " + dataSourceApp + " config not exists");
        }
        HikariDataSourceInfo dataSourceInfo = new HikariDataSourceInfo();
        dataSourceInfo.setDriverClassName(driverClassName);
        dataSourceInfo.setJdbcUrl(jdbcUrl);
        dataSourceInfo.setUsername(username);
        dataSourceInfo.setPassword(password);
        dataSourceInfo.setMaximumPoolSize(20);

        return dataSourceInfo;
    }

    /**
     * 切换数据源，注意：此操作会切换数据源，如果当前有事务，会直接提交事务，且切换之后注意切换回去
     *
     * @param dataSourceApp
     */
    public static void switchDataSource(String dataSourceApp) {
        PlatformTransactionManager platformTransactionManager = BeanTool.getBean(PlatformTransactionManager.class);
        if (platformTransactionManager != null) {
            TransactionDefinition transactionDefinition = BeanTool.getBean(TransactionDefinition.class);
            TransactionStatus transactionStatus = platformTransactionManager.getTransaction(transactionDefinition);
            boolean rollbackOnly = transactionStatus.isRollbackOnly();
            if (!rollbackOnly) {
                platformTransactionManager.commit(transactionStatus);
            }
        }
        CommonContext context = CommonContext.getContext();
        CustomContext customContext = context.getCustomContext();
        customContext.setDataSourceApp(dataSourceApp);
        logger.debug("manual switch dataSource: {}", dataSourceApp);
    }

    /**
     * 切换默认数据源，注意：此操作会切换数据源，如果当前有事务，会直接提交事务，且切换之后注意切换回去
     */
    public static void switchConfigDefaultDataSource() {
        PlatformTransactionManager platformTransactionManager = BeanTool.getBean(PlatformTransactionManager.class);
        if (platformTransactionManager != null) {
            TransactionDefinition transactionDefinition = BeanTool.getBean(TransactionDefinition.class);
            TransactionStatus transactionStatus = platformTransactionManager.getTransaction(transactionDefinition);
            boolean rollbackOnly = transactionStatus.isRollbackOnly();
            if (!rollbackOnly) {
                platformTransactionManager.commit(transactionStatus);
            }
        }
        CommonContext context = CommonContext.getContext();
        CustomContext customContext = context.getCustomContext();
        String defaultSource = getDefaultSource();
        customContext.setDataSourceApp(defaultSource);
        logger.debug("manual switch config default dataSource: {}", defaultSource);
    }

    /**
     * 切换请求默认数据源，注意：此操作会切换数据源，如果当前有事务，会直接提交事务，且切换之后注意切换回去
     */
    public static void switchRequestDefaultDataSource() {
        PlatformTransactionManager platformTransactionManager = BeanTool.getBean(PlatformTransactionManager.class);
        if (platformTransactionManager != null) {
            TransactionDefinition transactionDefinition = BeanTool.getBean(TransactionDefinition.class);
            TransactionStatus transactionStatus = platformTransactionManager.getTransaction(transactionDefinition);
            boolean rollbackOnly = transactionStatus.isRollbackOnly();
            if (!rollbackOnly) {
                platformTransactionManager.commit(transactionStatus);
            }
        }
        CommonContext context = CommonContext.getContext();
        CustomContext customContext = context.getCustomContext();
        customContext.setDataSourceApp(customContext.getApp());
        logger.debug("manual switch request default dataSource: {}", customContext.getApp());
    }


}
